package sublinear.model;

import java.util.ArrayList;

public abstract class AbstractGraph {

	public static class GraphNode implements Comparable<GraphNode> {
		
		public GraphNode(long id, String friendlyName)
		{
			this.id = id;
			this.friendlyName = friendlyName;
			this.color = NodeColor.White; //obsolete
		}
	
		public long getUniqueId()
		{
			return id;
		}
		
		public String getFriendlyName()
		{
			return friendlyName;
		}
		
		public void setColor(NodeColor color)
		{
			this.color = color;
		}
		
		public NodeColor getColor()
		{
			return color;
		}
		
		public void setDegree(int deg)
		{
			this.degree = deg;
		}
		
		public int getDegree()
		{
			return degree;
		}
		
		public void setNumEdges(int e)
		{
			this.numEdges = e;
		}
		
		public int getNumEdges()
		{
			return numEdges;
		}
		
		public int getIndex()
		{
			return index;
		}
		
		public void setIndex(int ind)
		{
			index = ind;
		}
		
		public int getLowlink()
		{
			return lowlink;
		}
		
		public void setLowlink(int low)
		{
			lowlink = low;
		}
		
		@Override
		public int compareTo(GraphNode g) {
			return new Long(getUniqueId()).compareTo(g.getUniqueId());
		}
		
		// 64 bit integer - a unique ID
		private long id;
		// Friendly name - useful for debugging. Might be empty
		private String friendlyName;
		// Color - if required for performing global graph algorithms
		private NodeColor color;
		// 32 bit integer - node degree
		private int degree = -1;
		// 32 bit integer - #edges in component
		private int numEdges = 0;
		
		// Tarjan (connected components algorithm) specific fields
		public int index = -1;
		public int lowlink = -1;
		public int vindex = -1;
		public GraphNode caller = null;
		
		public boolean notVisited() {
			return this.color == NodeColor.White;
		}

	}
	
	public abstract ArrayList<GraphNode> getNeighbors(GraphNode node);
	public abstract GraphNode getRandomNode();
	public abstract long getSize();
	
	/**
	 * Returns the degree, meaning the number of neighbors a specific 
	 * node has. This is a trivial implementation, overriding classes
	 * might use this or can provide a more efficient implementation
	 * 
	 * @param node Graph node to search
	 * @return Number of neighbors
	 */
	public long getDegree(GraphNode node)
	{
		return getNeighbors(node).size();
	}
	
}
